/**
 * @file uart_interface.c
 * @brief UART通信接口模块实现
 * @author 通信接口功能集成
 * @date 2024-07-06
 */

#include "uart_interface.h"
#include "sdk_project_config.h"
#include "vision_pose.h"
#include "global_vars.h"
#include "../ESWIN_SDK/log/include/log.h"

#include <string.h>
#include <stdio.h>

// UART5相关定义
#define UART5_INSTANCE INST_UART_5
#define UART2_INSTANCE INST_UART_2

// 缓冲区定义
static uint8_t uart_tx_buffer[64];

// 引用外部函数
extern void ProcessPositionUpdate(int position);
// 在文件顶部添加Vision_AdjustByK230声明
extern void Vision_AdjustByK230(int pos, float angle);

// 全局变量-控制UART5到UART2转发状态
static uint8_t g_uart5ToUart2ForwardEnabled = UART5_TO_UART2_FORWARD_ENABLED;

/**
 * @brief 通过UART发送字符串
 * @param instance UART实例编号
 * @param str 要发送的字符串
 */
void UART_SendString(uint32_t instance, const char* str)
{
    uint32_t len = strlen(str);
    if (len > sizeof(uart_tx_buffer) - 1) {
        len = sizeof(uart_tx_buffer) - 1;
    }
    
    memcpy(uart_tx_buffer, str, len);
    uart_tx_buffer[len] = '\0';
    
    UART_DRV_SendDataPolling(instance, uart_tx_buffer, len);
}

/**
 * @brief 通过UART发送二进制数据
 * @param instance UART实例编号
 * @param data 要发送的数据
 * @param length 数据长度
 */
void UART_SendData(uint32_t instance, const uint8_t* data, size_t length)
{
    if (length > sizeof(uart_tx_buffer)) {
        length = sizeof(uart_tx_buffer);
    }
    
    memcpy(uart_tx_buffer, data, length);
    
    UART_DRV_SendDataPolling(instance, uart_tx_buffer, length);
}

/**
 * @brief 发送测试数据给视觉模块，验证通信
 * 发送一条测试请求，请求视觉模块回传数据
 */
void UART_SendTestData(void)
{
    printf("[UART5] Sending test command to vision module...\r\n");
    
    // 先发送换行符，确保视觉模块处于接收状态
    UART_SendString(UART5_INSTANCE, "\r\n");
    DELAY_MS(50);
    
    // 发送测试命令 - 请求位置数据
    UART_SendString(UART5_INSTANCE, "$REQ,POS#\r\n");
    
    printf("[UART5] Test command sent, waiting for response...\r\n");
}

/**
 * @brief 处理UART接收到的数据
 * @param data 接收到的数据
 * @param length 数据长度
 */
void UART_ProcessData(uint8_t* data, size_t length)
{
    // 确保数据以null结尾
    static char buffer[UART_RX_BUFFER_SIZE];
    
    if (length >= sizeof(buffer)) {
        length = sizeof(buffer) - 1;
    }
    
    memcpy(buffer, data, length);
    buffer[length] = '\0';
    
    // 打印日志，显示收到的数据
    printf("\n==== UART5 Data Processing Start ====\r\n");
    printf("Received data length: %d bytes\r\n", length);
    printf("Received data content: \"%s\"\r\n", buffer);
    printf("Hex representation: ");
    for (int i = 0; i < length; i++) {
        printf("%02X ", buffer[i]);
    }
    printf("\r\n");
    
    // 检查是否是视觉模块数据
    bool isVisionData = (length > 5 && 
                        buffer[0] == '$' && 
                        buffer[1] == 'P' && 
                        buffer[2] == 'O' && 
                        buffer[3] == 'S' && 
                        buffer[4] == ',');
    
    printf("Data format check: %s vision module data format\r\n", isVisionData ? "Matches" : "Does not match");
    
    // 如果是视觉数据，处理
    if (isVisionData) {
        printf("Current car state: %d (0=IDLE,1=MOVING,2=WAITING,3=ADJUSTING,4=BUSY)\r\n", g_carState);
        
        // 如果当前状态是BUSY，不处理新的视觉数据
        if (g_carState == CAR_STATE_BUSY) {
            static uint32_t s_lastBusyMsgTime = 0;
            uint32_t currentTime = g_systemTimeMs;
            
            // 每隔一段时间才打印一次忙碌消息，避免过多输出
            if (currentTime - s_lastBusyMsgTime > 2000) {
                printf("Car is processing previous vision data, not accepting new data\r\n");
                s_lastBusyMsgTime = currentTime;
            }
            printf("State is BUSY, ignoring this vision data\r\n");
            printf("==== UART5 Data Processing End ====\r\n\n");
            return;
        }
        
        // 如果正在移动，也不处理视觉数据
        if (g_carState == CAR_STATE_MOVING) {
            printf("Car is currently moving, ignoring this vision data\r\n");
            printf("==== UART5 Data Processing End ====\r\n\n");
            return;
        }
        
        // 尝试解析视觉模块数据
        // 注释掉Vision_ParsePoseData和Vision_ProcessPoseCorrection相关代码
        // VisionPoseData poseData;
        // bool parseResult = Vision_ParsePoseData(buffer, &poseData);
        printf("==== Vision Data Parsing Result ====\r\n");
        printf("Current car state: %d (0=IDLE,1=MOVING,2=WAITING,3=ADJUSTING,4=BUSY)\r\n", g_carState);
        printf("Current position: %d, Target position: %d\r\n", g_currentPosition, g_targetPosition);
        printf("Vision data parsing %s\r\n", false ? "successful" : "failed"); // 模拟解析失败
        
        if (false) { // 模拟解析成功
            printf("Parsed data details:\r\n");
            printf("- Position: %d\r\n", 0); // 模拟位置
            printf("- Center X: %.1f\r\n", 0.0f); // 模拟中心X
            printf("- Center Y: %.1f\r\n", 0.0f); // 模拟中心Y
            printf("- Angle: %.1f°\r\n", 0.0f); // 模拟角度
            printf("- Distance: %.1f\r\n", 0.0f); // 模拟距离
            printf("- Skew: %.1f\r\n", 0.0f); // 模拟斜率
            
            // 设置状态为BUSY，在处理完成后会恢复
            g_carState = CAR_STATE_BUSY;
            printf("Car state changed to: BUSY\r\n");
            
            // 视觉处理逻辑
            printf("Starting vision-based position and posture processing\r\n");
            
            // 直接使用Vision_ProcessPoseCorrection处理完整的视觉姿态数据
            // 不再调用ProcessPositionUpdate处理简单的位置信息
            // Vision_ProcessPoseCorrection(&poseData);
            
            // 处理完成后，确保不再处于BUSY状态
            if (g_carState == CAR_STATE_BUSY) {
                printf("Vision processing completed, but still in BUSY state. Resetting to WAITING state.\r\n");
                g_carState = CAR_STATE_WAITING;
            }
            
            printf("==== UART5 Data Processing End ====\r\n\n");
            return;
        } else {
            printf("Parsing failure details: Format mismatch or invalid data\r\n");
            printf("==== UART5 Data Processing End ====\r\n\n");
        }
    } else {
        // 未知格式数据
        printf("Unknown data format, does not match vision data format\r\n");
    }
    
    // 在UART_ProcessData函数中，处理$POS数据时调用Vision_AdjustByK230
    // 解析K230二维码定位数据
    int pos = 0;
    float angle = 0;
    // 解析格式: $POS,位置,centerX,centerY,angle,distance,skew#
    char* token = strtok(buffer, ",#");
    int field = 0;
    while (token) {
        if (field == 1) pos = atoi(token);
        if (field == 4) angle = atof(token);
        token = strtok(NULL, ",#");
        field++;
    }
    Vision_AdjustByK230(pos, angle);
    
    printf("==== UART5 Data Processing End ====\r\n\n");
}

/**
 * @brief 初始化UART模块
 */
void UART_Interface_Init(void)
{
    // 初始化UART2用于日志输出
    UART_DRV_Init(UART2_INSTANCE, &g_stUartState_2, &g_stUart2UserConfig0);
    setLogPort(2);
    
    // 发送控制字符，设置终端模式为正确处理中文
    UART_SendData(UART2_INSTANCE, (const uint8_t*)"\x1B%G", 3);
    DELAY_MS(10);
    
    printf("\r\n\r\n=== UART Interface Module Initialized ===\r\n");
    
    // 初始化UART5用于视觉模块通信
    UART_DRV_Init(UART5_INSTANCE, &g_stUartState_5, &g_stUart5UserConfig0);
    
    // 设置UART5的FIFO水位线为1，确保对每个接收字节立即响应
    UART_DRV_FIFOWater_Init(UART5_INSTANCE, 1);
    
    // 启用UART5接收中断敏感度设置
    printf("[UART] Setting UART5 receive sensitivity...\r\n");
    
    // 发送初始化完成消息
    printf("UART5 initialization complete, ready to receive vision module data\r\n");
    printf("Supported data format: $POS,position,centerX,centerY,angle,distance,skew#\r\n");
    
    // 延迟一段时间后发送测试命令
    DELAY_MS(500);
    UART_SendTestData();
}

/**
 * @brief 设置UART5到UART2的转发状态
 * @param enable 是否启用转发 (1=启用, 0=禁用)
 */
void UART_SetForwarding(uint8_t enable)
{
    g_uart5ToUart2ForwardEnabled = enable ? 1 : 0;
    printf("[UART] UART5 to UART2 forwarding %s\r\n", enable ? "enabled" : "disabled");
}

/**
 * @brief UART接收循环
 * 在主循环中调用此函数以接收完整的数据包
 * 支持处理连续的多个数据包
 */
void UART_ReceiveLoop(void)
{
    static uint8_t rx_buffer[UART_RX_BUFFER_SIZE];
    static size_t rx_count = 0;
    uint8_t rx_byte;
    static uint32_t last_byte_time = 0;
    static uint32_t last_status_time = 0;
    uint32_t current_time = g_systemTimeMs;
    
    // 定期打印UART5接收状态信息(每3秒)
    if (current_time - last_status_time > 3000) {
        printf("[UART5] Status: buffer_used=%d, last_byte=%lu ms ago\r\n", 
               rx_count, current_time - last_byte_time);
        
        // 如果有数据但长时间没有收到新字节，可能是接收被中断
        if (rx_count > 0 && current_time - last_byte_time > 5000) {
            printf("[UART5] Reception seems stuck. Current buffer: ");
            for (int i = 0; i < rx_count && i < 32; i++) {
                printf("%c", rx_buffer[i] >= 32 && rx_buffer[i] <= 126 ? rx_buffer[i] : '.');
            }
            printf("\r\n");
            
            // 打印十六进制格式，帮助调试
            printf("[UART5] Buffer HEX: ");
            for (int i = 0; i < rx_count && i < 32; i++) {
                printf("%02X ", rx_buffer[i]);
            }
            printf("\r\n");
            
            // 如果缓冲区开头是$POS但没有收到#结束符，尝试强制处理
            if (rx_count >= 5 && 
                rx_buffer[0] == '$' && rx_buffer[1] == 'P' && 
                rx_buffer[2] == 'O' && rx_buffer[3] == 'S' && rx_buffer[4] == ',') {
                printf("[UART5] Found incomplete $POS data, forcing termination\r\n");
                rx_buffer[rx_count] = '#';  // 添加结束符
                rx_buffer[rx_count+1] = '\0';
                UART_ProcessData(rx_buffer, rx_count+1);
            }
            
            // 重置缓冲区
            rx_count = 0;
            
            // 如果长时间卡住，重新初始化UART5
            UART_ReinitReceiver();
        }
        last_status_time = current_time;
    }

    // ===== 修改部分：串口接收逻辑优化 =====
    
    // 接收状态控制
    static bool waiting_for_packet = false; // 标记是否正在等待数据包的剩余部分
    static uint32_t packet_start_time = 0;  // 记录数据包开始接收的时间
    
    // 批量读取数据尝试，视觉模块可能一次性发送大量数据
    uint8_t temp_buffer[64];  // 临时缓冲区
    uint32_t bytes_read = 0;
    
    // 首先尝试一次性读取多个字节（快速模式）
    status_t batch_status = UART_DRV_ReceiveDataPolling(UART5_INSTANCE, temp_buffer, 
                                                       sizeof(temp_buffer) - 1);
    
    if (batch_status == STATUS_SUCCESS) {
        // 计算实际读取的字节数
        for (bytes_read = 0; bytes_read < sizeof(temp_buffer) - 1; bytes_read++) {
            if (temp_buffer[bytes_read] == 0) break;  // 遇到空字符结束
        }
        
        if (bytes_read > 0) {
            printf("[UART5] Batch received %d bytes\r\n", (int)bytes_read);
            
            // 检查是否形成完整数据包（包含$和#）
            bool has_start = false;
            bool has_end = false;
            size_t start_pos = 0;
            size_t end_pos = 0;
            
            for (size_t i = 0; i < bytes_read; i++) {
                if (temp_buffer[i] == '$') {
                    has_start = true;
                    start_pos = i;
                }
                if (temp_buffer[i] == '#' && has_start) {
                    has_end = true;
                    end_pos = i;
                    break;
                }
            }
            
            if (has_start && has_end) {
                // 找到完整数据包
                size_t packet_len = end_pos - start_pos + 1;
                printf("[UART5] Found complete packet in batch data: ");
                for (size_t i = start_pos; i <= end_pos; i++) {
                    printf("%c", temp_buffer[i] >= 32 && temp_buffer[i] <= 126 ? temp_buffer[i] : '.');
                }
                printf("\r\n");
                
                // 处理这个数据包
                UART_ProcessData(&temp_buffer[start_pos], packet_len);
                
                // 重置接收状态
                rx_count = 0;
                waiting_for_packet = false;
                last_byte_time = current_time;
                return;  // 已处理完数据包，直接返回
            }
            
            // 如果没有形成完整数据包，将数据添加到缓冲区
            for (size_t i = 0; i < bytes_read && rx_count < sizeof(rx_buffer) - 1; i++) {
                rx_buffer[rx_count++] = temp_buffer[i];
                last_byte_time = current_time;
                
                // 打印接收到的字节
                printf("[UART5] Batch byte %zu: '%c' (0x%02X)\r\n", 
                       i, temp_buffer[i] >= 32 && temp_buffer[i] <= 126 ? temp_buffer[i] : '.', 
                       temp_buffer[i]);
                
                // 如果收到'$'，设置等待数据包状态
                if (temp_buffer[i] == '$' && rx_count == 1) {
                    waiting_for_packet = true;
                    packet_start_time = current_time;
                }
                
                // 如果接收到'#'并且缓冲区中有'$'，说明是完整数据包
                if (temp_buffer[i] == '#' && rx_buffer[0] == '$') {
                    rx_buffer[rx_count] = '\0';  // 添加字符串结束符
                    printf("[UART5] Complete packet in buffer: %s\r\n", rx_buffer);
                    
                    // 处理数据包
                    UART_ProcessData(rx_buffer, rx_count);
                    
                    // 重置缓冲区
                    rx_count = 0;
                    waiting_for_packet = false;
                    return;  // 处理完成，直接返回
                }
            }
        }
    }
    
    // 如果我们已经接收了$符号但还未完成整个数据包，额外延长接收等待时间
    if (rx_count > 0 && rx_buffer[0] == '$' && waiting_for_packet) {
        // 计算数据包接收已经等待的时间
        uint32_t wait_time = current_time - packet_start_time;
        
        // 强制多次尝试接收以获取完整数据包
        uint32_t intensive_attempts = 200;  // 增加密集接收尝试次数
        bool packet_complete = false;
        
        // 永不超时，持续等待数据
        printf("[UART5] Actively waiting for more data after '$'... (waited %lu ms)\r\n", wait_time);
        
        // 在接收到$后，持续尝试接收更多数据，直到包完整或尝试次数用尽
        for (uint32_t i = 0; i < intensive_attempts; i++) {
            // 每次接收前稍微等待，让更多数据进入缓冲区
            DELAY_MS(5);  // 减少单次等待时间，但增加尝试次数
            
            // 尝试接收更多字节
            status_t status = UART_DRV_ReceiveDataPolling(UART5_INSTANCE, &rx_byte, 1);
            if (status == STATUS_SUCCESS) {
                // 打印接收到的字节（使用英文，避免中文显示问题）
                printf("[UART5] Continued: '%c' (0x%02X)\r\n", 
                       rx_byte >= 32 && rx_byte <= 126 ? rx_byte : '.', rx_byte);
                
                // 转发到调试控制台（简化输出）
                if (g_uart5ToUart2ForwardEnabled) {
                    printf("   %c", rx_byte >= 32 && rx_byte <= 126 ? rx_byte : '.');
                }
                
                // 添加到缓冲区
                if (rx_count < sizeof(rx_buffer) - 1) {
                    rx_buffer[rx_count++] = rx_byte;
                    last_byte_time = current_time;
                }
                
                // 如果收到结束符或换行符，处理数据包并退出循环
                if (rx_byte == '#' || rx_byte == '\n' || rx_byte == '\r') {
                    packet_complete = true;
                    
                    if (rx_byte != '#') {
                        printf("[UART5] Packet terminated by line ending (not #)\r\n");
                    }
                    
                    break;
                }
                
                // 接收到有效数据，重置尝试计数器继续接收
                i = 0; // 重置尝试次数
            }
        }
        
        // 如果收到完整数据包，进行处理
        if (packet_complete) {
            rx_buffer[rx_count] = '\0';  // 确保以null结尾
            printf("[UART5] Packet completed: %s\r\n", rx_buffer);
            
            // 打印十六进制格式，帮助调试
            printf("[UART5] Buffer HEX: ");
            for (int i = 0; i < rx_count && i < 32; i++) {
                printf("%02X ", rx_buffer[i]);
            }
            printf("\r\n");
            
            // 处理数据包
            UART_ProcessData(rx_buffer, rx_count);
            
            // 重置状态
            rx_count = 0;
            waiting_for_packet = false;
            return; // 处理完毕，直接返回
        } else {
            // 仍未收到完整数据包，保持等待状态，让下一次调用继续尝试
            printf("[UART5] Still waiting for complete packet... (current data: ");
            for (int i = 0; i < rx_count && i < 32; i++) {
                printf("%c", rx_buffer[i] >= 32 && rx_buffer[i] <= 126 ? rx_buffer[i] : '.');
            }
            printf(")\r\n");
            
            // 不超时，继续保持等待状态
            return;
        }
    }
    
    // 标准接收流程，尝试接收新数据
    uint32_t max_attempts = 32;
    uint32_t attempts = 0;
    bool got_data = false;
    
    while (attempts < max_attempts) {
        // 尝试接收单个字节
        status_t status = UART_DRV_ReceiveDataPolling(UART5_INSTANCE, &rx_byte, 1);
        
        if (status == STATUS_SUCCESS) {
            got_data = true;
            attempts = 0;  // 重置尝试计数
            
            // 打印接收到的字节
            printf("[UART5] Received: '%c' (0x%02X)\r\n", 
                   rx_byte >= 32 && rx_byte <= 126 ? rx_byte : '.', rx_byte);
            
            // 转发到调试控制台
            if (g_uart5ToUart2ForwardEnabled) {
                printf("   %c", rx_byte >= 32 && rx_byte <= 126 ? rx_byte : '.');
            }
            
            // 添加到接收缓冲区
            if (rx_count < sizeof(rx_buffer) - 1) {
                rx_buffer[rx_count++] = rx_byte;
                last_byte_time = current_time;
            }
            
            // 检查是否收到起始符号'$'
            if (rx_byte == '$' && rx_count == 1) {
                printf("[UART5] Start of packet detected, switching to intensive reception mode\r\n");
                waiting_for_packet = true;
                packet_start_time = current_time;  // 记录数据包开始时间
                
                // 尝试立即读取后续字节
                DELAY_MS(20);  // 给视觉模块时间准备后续数据
                continue;  // 立即继续循环尝试接收更多数据
            }
            
            // 检查是否收到结束符号'#'或换行符
            if (rx_byte == '#' || rx_byte == '\n' || rx_byte == '\r') {
                if (rx_byte != '#') {
                    printf("[UART5] Non-standard terminator received (%02X)\r\n", rx_byte);
                }
                
                rx_buffer[rx_count] = '\0';  // 确保以null结尾
                printf("[UART5] Complete packet received: %s\r\n", rx_buffer);
                
                // 处理完整数据包
                UART_ProcessData(rx_buffer, rx_count);
                
                // 重置缓冲区
                rx_count = 0;
                waiting_for_packet = false;
                break;
            }
        } else {
            // 无数据可接收
            attempts++;
            
            // 如果收到了一些数据但未收到完整包，不要立即退出
            if (got_data && rx_count > 0) {
                // 在接收了部分数据后，使用较长的等待时间
                if (attempts % 4 == 0) {
                    DELAY_MS(5);
                }
            } else {
                // 没有接收到任何数据，使用较短的等待时间
                if (attempts % 16 == 0) {
                    DELAY_MS(1);
                }
            }
        }
    }
    
    // 如果多次尝试后还收不到数据，可能需要重置UART
    static uint32_t no_data_counter = 0;
    
    if (!got_data) {
        no_data_counter++;
        
        // 如果连续1000次（约10秒）没有收到数据，尝试重置UART5
        if (no_data_counter > 1000) {
            printf("[UART5] No data received for a long time, resetting UART5...\r\n");
            
            // 调用UART重新初始化函数
            UART_ReinitReceiver();
            
            // 重置计数器和接收缓冲区
            no_data_counter = 0;
            rx_count = 0;
            waiting_for_packet = false;
        }
    } else {
        // 成功接收数据，重置无数据计数器
        no_data_counter = 0;
    }
}

/**
 * @brief 重新初始化UART5接收器
 * 当检测到UART5接收出现问题时，调用此函数重置UART5
 */
void UART_ReinitReceiver(void)
{
    printf("[UART5] Performing complete UART5 reinitialization...\r\n");
    
    // 完全关闭并重新初始化UART5
    UART_DRV_Deinit(UART5_INSTANCE);
    
    // 延时等待硬件稳定
    DELAY_MS(100);
    
    // 重新初始化UART5
    UART_DRV_Init(UART5_INSTANCE, &g_stUartState_5, &g_stUart5UserConfig0);
    
    // 设置FIFO水位线为1，确保每个字节都触发接收
    UART_DRV_FIFOWater_Init(UART5_INSTANCE, 1);
    
    // 清空UART5的接收缓冲区
    uint8_t dummy;
    while (UART_DRV_ReceiveDataPolling(UART5_INSTANCE, &dummy, 1) == STATUS_SUCCESS) {
        // 持续读取直到缓冲区为空
    }
    
    // 再次短暂延迟确保初始化完成
    DELAY_MS(50);
    
    // 发送重置确认消息
    UART_SendString(UART5_INSTANCE, "UART5 has been completely reinitialized\r\n");
    printf("[UART5] Reinitialization complete\r\n");
} 